package com.nicolasprof.profgallery {
	import gs.plugins.*;

	import com.hexagonstar.util.debug.Debug;
	import com.nicolasprof.profgallery.controls.Controls;
	import com.nicolasprof.profgallery.infopanel.InfoPanel;
	import com.nicolasprof.profgallery.layers.LayerManager;
	import com.nicolasprof.profgallery.navigation.Categories;
	import com.nicolasprof.profgallery.thumbs.Thumbnail;
	import com.nicolasprof.profgallery.thumbs.Thumbs;
	import com.nicolasprof.profgallery.utils.SlideShow;
	import com.nicolasprof.profgallery.utils.TooltipHandler;
	import com.nicolasprof.profgallery.viewer.ImageHolder;

	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;

	/**
	 * @author Nicolas Prof
	 */
	public class Engine extends Sprite {
		
		public static const VERSION:String ="3.0.1";
		public static var CONFIG_XML : XML;
		public static var DATA_XML : XML;

		private var _pathConfig : String;
		private var _imageHolder : ImageHolder;
		private var _categories : Categories;
		private var _thumbs : Thumbs;
		private var _slideShow : SlideShow;
		private var _controls : Controls;
		private var _infoPanel : InfoPanel;

		
		
		public function Engine() {
			addEventListener(Event.ADDED_TO_STAGE, onAdded);
		}	
		public function buildMenu() : void {
			_categories.build();
		}
		private function init() : void {
			Debug.trace("PROFGallery : Initiate", 0);
			
			TweenPlugin.activate([AutoAlphaPlugin, ColorTransformPlugin, BlurFilterPlugin, TintPlugin, ColorMatrixFilterPlugin]);
			
			var config : XML = Engine.CONFIG_XML;
			var width:Number = Number(config.viewer.@width);
			var height:Number = Number(config.viewer.@height);
			var th : TooltipHandler = TooltipHandler.getInstance();
			_imageHolder = new ImageHolder(width, height, this);
			_thumbs = new Thumbs(getEngineThumbListeners());
			_controls = new Controls(this);
			_slideShow = new SlideShow(this);	
			_categories = new Categories(this);
			
			
			//Display list
			addChild(_imageHolder);
			addChild(_controls);
			addChild(_thumbs);	
			
			//Actions
			
			th.stage = this.stage;
			th.enabled = String(config.tip.@active).toLowerCase() == "true";
			
			//LAYOUT CONTROL
			_imageHolder.x = Number(config.viewer.@posX);
			_imageHolder.y = Number(config.viewer.@posY);
			
			_thumbs.x = Number(config.thumbnail.@posX);
			_thumbs.y = Number(config.thumbnail.@posY);
			
			if(String(config.infopanel.@active).toLowerCase() == "true") {
				_infoPanel = new InfoPanel();
				_infoPanel.initiate(width, height);
				
				_imageHolder.addEventListener(MouseEvent.MOUSE_OVER, onOverViewer);
				_imageHolder.addEventListener(MouseEvent.MOUSE_OUT, onOutViewer);
				
				this.addChildAt(_infoPanel, this.getChildIndex(_imageHolder) + 1);
				
				_infoPanel.x = _imageHolder.x;
				_infoPanel.y = _imageHolder.y + height;
			}
			
			//THUMBNAILS
			_thumbs.draw();
			
			//CheckLayers
			new LayerManager(this);
		}
		private function getDataPath() : String {
			return (Engine.CONFIG_XML.data.@path != "") ? Engine.CONFIG_XML.data.@path : Engine.CONFIG_XML..menu.(attribute("default") == "true")[0].@url;
		}		
		private function getEngineThumbListeners() : Object {
			var obj : Object = {};
			obj[MouseEvent.CLICK] = onClickThumbnail;
			return obj;
		}		
		public function getCurrentURL() : String {
			if(_thumbs != null){
				return _thumbs.selected.url;
			}
			return "";
		}
		private function loadXML($path : String, $vars: URLVariables = null, onComplete : Function = null, onProgress: Function = null) : void {
			var request : URLRequest = new URLRequest();
			request.method = URLRequestMethod.POST;
			request.url = $path;
			request.data = $vars;
			var loader : URLLoader = new URLLoader();
			if(onComplete != null) loader.addEventListener(Event.COMPLETE, onComplete, false, 0, true);
			if(onProgress != null) loader.addEventListener(ProgressEvent.PROGRESS, onProgress, false, 0, true);
			loader.load(request);
		}
		
		//CHECK FLASHVARS
		private function reciveFlashVars():void {
			var paramObj:Object = this.stage.loaderInfo.parameters;
			_pathConfig = paramObj.pathConfig || "./xml/config.xml";
		}	
		public function selectThumbnail($offset : int) : void {
			_thumbs.selectByOffset($offset);
		}	
		public function toggleSlideshow() : void {
			_slideShow.toggle();
		}	
		public function updateCategory($path : String) : void {
			_slideShow.enabled = false;
			_controls.disableSlideshow();
			_thumbs.clear();
			loadXML($path, null, onCompleteData);
		}
		/**
		 * Events
		 */
		private function onAdded(e : Event) : void {
			
			removeEventListener(Event.ADDED_TO_STAGE, onAdded);
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            
            Debug.enabled = true;
            Debug.clear();
            
            reciveFlashVars();
			loadXML(_pathConfig, null, onCompleteLoadConfig);
		}
		protected function onCompleteData(e : Event) : void {
			Engine.DATA_XML = new XML(e.target.data);
			_thumbs.draw();
			_categories.removeBlockLayer();
		}	
		private function onClickThumbnail(e : MouseEvent) : void {
			if(e.target is Thumbnail){
				var thumb : Thumbnail = e.target as Thumbnail;
				_imageHolder.loadPhoto(thumb.mainURL);
				_controls.updatePosition(thumb.pos + 1, Engine.DATA_XML..img.length());
				if(_infoPanel){
					_infoPanel.text = {title : thumb.title , desc :  thumb.desc};
				}
			}
		}
		private function onCompleteInitData(e : Event) : void {
			Engine.DATA_XML = new XML(e.target.data);
			init();
		}
		private function onCompleteLoadConfig(e : Event) : void {
			Engine.CONFIG_XML = new XML(e.target.data);
			loadXML(getDataPath(), null, onCompleteInitData);
		}
		private function onOverViewer(e : MouseEvent) : void {
			if(_infoPanel != null){
				_infoPanel.toggle(true);
			}
		}
		private function onOutViewer(e : MouseEvent) : void {
			if(_infoPanel != null){
				_infoPanel.toggle(false);
			}
		}
		/**
		 * Getters
		 */
		public function get imageHolder() : ImageHolder {
			return _imageHolder;
		}
	}
}
